package com.example.im.util;

import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Redis工具类
 */
@Component
@Order(0)
public class RedisUtil {

	@Autowired(required=false)
	private RedissonClient redissonClient;

	/** 不设置过期时长 */
	public final static long NOT_EXPIRE = -1L;

	@Value("${redisson-config-usecache : true}")
	private boolean useCache;


	/**
	 * 设置到缓存
	 * @param key   键
	 * @param value  值
	 * @param expire  超时时间,秒
	 */
	public void set(String key, Object value, long expire) {
		if(!useCache) {
			return;
		}
		RBucket<Object> bucket = redissonClient.getBucket(key);
		bucket.set(value);
		if (expire != NOT_EXPIRE) {
			bucket.expire(expire, TimeUnit.SECONDS);
		}
	}

	/**
	 * 设置到缓存, 永不超时
	 * @param key 键
	 * @param value  值
	 */
	public void set(String key, Object value) {
		set(key, value, NOT_EXPIRE);
	}


	/**
	 * 获取缓存对象
	 * @param key  键
	 * @param clazz  值对象类型
	 * @return
	 */
	public <T> T get(String key, Class<T> clazz) {
		if(!useCache) {
			return null;
		}
		RBucket<T> bucket = redissonClient.getBucket(key);
		return bucket.get();
	}

	/**
	 * 获取String
	 * @param key
	 * @return
	 */
	public String getString(String key) {
		String obj = get(key, String.class);
		return obj;
	}


	/**
	 * 删除缓存记录
	 * @param key
	 */
	public void delete(String key) {
		if(!useCache) {
			return;
		}
		RBucket<Object> bucket = redissonClient.getBucket(key);
		bucket.delete();
	}


	/**
	 * 获取非公平锁
	 * @param key
	 * @return
	 */
	public RLock getLock(String key) {
		return redissonClient.getLock(getLockKey(key));
	}



	/**
	 * 获取公平锁
	 * @param key
	 * @return
	 */
	public RLock getFairLock(String key) {
		return redissonClient.getFairLock(getLockKey(key));
	}


	/**
	 * 获取读写锁
	 * @param key
	 * @return
	 */
	public RReadWriteLock getReadWriteLock(String key) {
		return redissonClient.getReadWriteLock(getLockKey(key));
	}

	/**
	 * 全局锁key
	 * @param key
	 * @return
	 */
	private final static String getLockKey(String key) {
		return "logistics_lock:" + key;
	}
}
